package com.mcxx.modules.fund.service;

import cn.hutool.core.date.DateUtil;
import com.mcxx.common.exception.BizException;
import com.mcxx.constant.DictConstant;
import com.mcxx.constant.MQConstant;
import com.mcxx.modules.base.service.read.DictionaryReadService;
import com.mcxx.modules.miniSalvation.fundpay.dto.CapitalFundPayDTO;
import com.mcxx.modules.miniSalvation.fundpay.dto.FuneralFundPayDTO;
import com.mcxx.modules.miniSalvation.fundpay.service.read.FundPayFamilyReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.read.FundPayReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.write.FundPayWriteService;
import com.mcxx.modules.system.dto.MQMessageDTO;
import com.mcxx.modules.temporary.fundpay.dao.read.TmpFundPayReadDao;
import com.mcxx.modules.temporary.fundpay.dto.TmpFundPayDTO;
import com.mcxx.modules.temporary.fundpay.service.read.TmpFundPayFamilyReadService;
import com.mcxx.modules.temporary.fundpay.service.write.TmpFundPayWriteService;
import com.mcxx.result.BaseResult;
import com.mcxx.util.*;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import com.yinhai.ta404.module.dict.entity.TaDictPo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


@Slf4j
@Service
@TaTransactional
public class FundPayService {
    @Autowired
    private TmpFundPayFamilyReadService tmpFundPayFamilyReadService;
    @Autowired
    private TmpFundPayWriteService tmpFundPayWriteService;
    @Autowired
    private FundPayReadService fundPayReadService;
    @Autowired
    private FundPayWriteService fundPayWriteService;
    @Autowired
    private FundPayFamilyReadService fundPayFamilyReadService;
    @Autowired
    private DictionaryReadService dictionaryReadService;
    @Autowired
    private TmpFundPayReadDao tmpFundPayReadDao;
    @Autowired
    private AreaUtil areaUtil;


    public BaseResult<Boolean> addTempFundPay(String areaCode, String payDate, String payWay, String isAuto) {
        if(CommonUtil.invalidArgs(areaCode) || areaCode.length() != 12
            || CommonUtil.invalidArgs(payDate) || payDate.length() != 6) {
            throw new BizException(FailureCode.ERR_10001);
        }

        if(CommonUtil.invalidArgs(payWay)){
            payWay = "01";
        }


        TmpFundPayDTO tmpFundPayDTO = new TmpFundPayDTO();
        tmpFundPayDTO.setAreaCode(areaCode);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        BaseResult<Boolean> result = new BaseResult<Boolean>();
        result.setData(false);
        Date pdate = null;
        try {
            pdate = sdf.parse(payDate + "01");
        } catch (ParseException e) {
            e.printStackTrace();
            result.setMsg("日期格式错");
            return result;
        }
        tmpFundPayDTO.setPayType("01");
        tmpFundPayDTO.setPayWay(payWay);
        tmpFundPayDTO.setPayDate(pdate);
        tmpFundPayDTO.setIsAuto(isAuto);
        UserAccountVo userAccountVo = new UserAccountVo();
        userAccountVo.setAreaCode(areaCode);
        userAccountVo.setAreaLevel(""+areaUtil.getLevelByAreaCode(areaCode));


        int fundNum = tmpFundPayReadDao.getFundPayNum(payWay, areaCode,
                DateUtil.format(pdate, "yyyy-MM-dd"), null);
        TaDictPo taDictPo = dictionaryReadService.getCodeCache(DictConstant.PAYMENT_MANNER, payWay);
        if(null == taDictPo){
            throw new BizException(FailureCode.ERR_10001);
        }
        String fundName = DateUtil.format(pdate, "yyyy年MM月") + "第" +  (fundNum + 1) + "批" + taDictPo.getLabel() + "发放名册";
        tmpFundPayDTO.setFundName(fundName);


        tmpFundPayFamilyReadService.cntFamilyByCapital(tmpFundPayDTO, userAccountVo);
        log.info("查询可以加入名册的家庭数据结束，地区{}",areaCode);

        tmpFundPayWriteService.insertCapital(tmpFundPayDTO, userAccountVo);
        log.info("生成{}地区，发放名册",areaCode);

        result.setData(true);
        return result;
    }


    public BaseResult<Boolean> addCapitalFundPay(String areaCode, String payDate, String standType, String isAuto) {

        CapitalFundPayDTO capitalFundPayDTO = new CapitalFundPayDTO();
        capitalFundPayDTO.setAreaCode(areaCode);
        capitalFundPayDTO.setBusinessType(Constant.BusinessCode.DIBAO);
        capitalFundPayDTO.setFundType(Constant.FundType.CAPITAL_FUND_PAY);
        capitalFundPayDTO.setPayType(Constant.FundType.CAPITAL_FUND_PAY);
        capitalFundPayDTO.setIsAuto(isAuto);

        BaseResult<Boolean> result = new BaseResult<Boolean>();
        result.setData(false);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date pdate = null;
        try {
            pdate = sdf.parse(payDate + "01");
        } catch (ParseException e) {
            e.printStackTrace();
            result.setMsg("日期格式错");
            return result;
        }
        capitalFundPayDTO.setPayDate(pdate);
        capitalFundPayDTO.setStandType(standType);

        UserAccountVo userAccountVo = new UserAccountVo();
        userAccountVo.setAreaCode(areaCode);
        userAccountVo.setAreaLevel(""+areaUtil.getLevelByAreaCode(areaCode));

        saveCapitalFundPay(capitalFundPayDTO, userAccountVo);

        result.setData(true);
        return result;
    }


    public BaseResult<Boolean> addExCapitalFundPay(String areaCode, String payDate, String standType, String supplyType,
                                                   String costType, String isAuto) {

        CapitalFundPayDTO capitalFundPayDTO = new CapitalFundPayDTO();
        capitalFundPayDTO.setAreaCode(areaCode);
        capitalFundPayDTO.setBusinessType(Constant.BusinessCode.TEKUN);
        capitalFundPayDTO.setFundType(Constant.FundType.CAPITAL_FUND_PAY);
        capitalFundPayDTO.setPayType(Constant.FundType.CAPITAL_FUND_PAY);
        capitalFundPayDTO.setIsAuto(isAuto);

        BaseResult<Boolean> result = new BaseResult<Boolean>();
        result.setData(false);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date pdate = null;
        try {
            pdate = sdf.parse(payDate + "01");
        } catch (ParseException e) {
            e.printStackTrace();
            result.setMsg("日期格式错");
            return result;
        }
        capitalFundPayDTO.setPayDate(pdate);
        capitalFundPayDTO.setStandType(standType);
        capitalFundPayDTO.setSupplyType(supplyType);
        capitalFundPayDTO.setCostType(costType);

        UserAccountVo userAccountVo = new UserAccountVo();
        userAccountVo.setAreaCode(areaCode);
        userAccountVo.setAreaLevel(""+areaUtil.getLevelByAreaCode(areaCode));

        saveCapitalFundPay(capitalFundPayDTO, userAccountVo);

        result.setData(true);
        return result;
    }

    public void saveCapitalFundPay(CapitalFundPayDTO capitalFundPayDTO, UserAccountVo userAccountVo){

        fundPayReadService.cntCapitalFundPay(capitalFundPayDTO);


        fundPayFamilyReadService.cntFamilyByCapitalList(capitalFundPayDTO, userAccountVo);


        fundPayWriteService.insertCapital(capitalFundPayDTO, userAccountVo);
    }


    public BaseResult<Boolean> addFuneralFundPay(String areaCode, String payDate, String standType, String takeType, String isAuto) {
        BaseResult<Boolean> result = new BaseResult<Boolean>();
        result.setData(false);

        FuneralFundPayDTO funeralFundPayDTO = getFuneralFundPayDTO(areaCode, payDate, standType, isAuto, takeType);

        UserAccountVo userAccountVo = new UserAccountVo();
        userAccountVo.setAreaCode(areaCode);
        userAccountVo.setAreaLevel(""+areaUtil.getLevelByAreaCode(areaCode));

        saveFuneralFundPay(funeralFundPayDTO, userAccountVo);

        result.setData(true);
        return result;
    }


    private FuneralFundPayDTO getFuneralFundPayDTO(String areaCode, String payDate, String standType, String isAuto, String takeType) {
        FuneralFundPayDTO funeralFundPayDTO = new FuneralFundPayDTO();
        funeralFundPayDTO.setAreaCode(areaCode);
        funeralFundPayDTO.setBusinessType(Constant.BusinessCode.TEKUN);
        funeralFundPayDTO.setFundType(Constant.FundType.FUNERAL_FUND_PAY);
        funeralFundPayDTO.setPayType(Constant.FundType.FUNERAL_FUND_PAY);
        funeralFundPayDTO.setIsAuto(isAuto);
        funeralFundPayDTO.setRecevierType(takeType);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date pdate = null;
        try {
            pdate = sdf.parse(payDate + "01");
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException("日期格式错");
        }
        funeralFundPayDTO.setPayDate(pdate);
        funeralFundPayDTO.setStandType(standType);
        return funeralFundPayDTO;
    }


    private void saveFuneralFundPay(FuneralFundPayDTO funeralFundPayDTO, UserAccountVo userAccountVo) {

        fundPayReadService.cntFuneral(funeralFundPayDTO);


        fundPayReadService.cntMemberByCreateFuneralOld(funeralFundPayDTO, userAccountVo);


        fundPayWriteService.insertFuneral(funeralFundPayDTO, userAccountVo);
    }
}
